package android.cmpe451.group7.activity;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.gson.reflect.TypeToken;
import android.cmpe451.group7.activity.R;
import android.cmpe451.group7.dbrequest.RetrieveJSONTask;
import android.cmpe451.group7.dbrequest.WebServiceResponse;
import android.cmpe451.group7.entity.Tag;
import android.cmpe451.group7.util.GlobalVariables;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.AdapterView.OnItemClickListener;

/**
 * @author Search places with given country, city, place name and tags
 *         information given by the user.
 * 
 */
public class SearchActivity extends Activity {
	public final static String EXTRA_MESSAGE = "com.example.ourcity_android.MESSAGE";
	List<Tag> data;
	String selectedTagMID = "";
	ArrayAdapter<String> adapterCity;
	ArrayAdapter<String> adapterCountry;
	ArrayAdapter<Tag> adapterTag;
	AutoCompleteTextView cityAutoComplete;
	AutoCompleteTextView countryAutoComplete;
	AutoCompleteTextView tagAutoComplete;

	Activity thisActivity;

	private Filter cityFilter;
	private Filter tagFilter;
	private static final int AUTOCOMPLETE_TRESHOLD = 2;

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_search);

		Resources res = getResources();
		String[] countries = res.getStringArray(R.array.countries_array);
		adapterCountry = new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, countries);

		tagAutoComplete = (AutoCompleteTextView) findViewById(R.id.tagAutoComplete);
		tagAutoComplete.setThreshold(AUTOCOMPLETE_TRESHOLD);
		tagAutoComplete.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				selectedTagMID = data.get(position).getmID();
			}

		});

		countryAutoComplete = (AutoCompleteTextView) findViewById(R.id.countryAutoComplete);
		countryAutoComplete.setAdapter(adapterCountry);

		cityAutoComplete = (AutoCompleteTextView) findViewById(R.id.cityAutoComplete);
		cityAutoComplete.setThreshold(AUTOCOMPLETE_TRESHOLD);

		// FILTER FOR CITY AUTOCOMPLETE
		cityFilter = new Filter() {
			@Override
			protected void publishResults(CharSequence constraint,
					FilterResults results) {
			}

			@Override
			protected FilterResults performFiltering(CharSequence constraint) {
				if (constraint != null
						&& constraint.length() > AUTOCOMPLETE_TRESHOLD) {

					Log.w("CONSTRAINT-SIZE", "SONRASI");
					new CityAdapterUpdaterTask().execute();
					Log.w("ADAPTER-UPDATER-TASK", "SONRASI");
				}
				return null;
			}
		};

		adapterCity = new ArrayAdapter<String>(this,
				android.R.layout.simple_dropdown_item_1line) {
			public android.widget.Filter getFilter() {
				return cityFilter;
			}
		};
		// FILTER FOR TAG AUTOCOMPLETE
		tagFilter = new Filter() {
			@Override
			protected void publishResults(CharSequence constraint,
					FilterResults results) {
			}

			@Override
			protected FilterResults performFiltering(CharSequence constraint) {
				if (constraint != null
						&& constraint.length() > AUTOCOMPLETE_TRESHOLD) {

					Log.w("CONSTRAINT-SIZE", "SONRASI");

					String tag = tagAutoComplete.getText().toString();
					adapterTag.clear();
					String url = "";
					try {
						url = String.format(GlobalVariables.get_tags,
								URLEncoder.encode(tag, "ISO-8859-1"));
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}

					new TagTask().execute(url);
					Log.w("ADAPTER-UPDATER-TASK", "SONRASI");
				}
				return null;
			}
		};

		adapterTag = new ArrayAdapter<Tag>(this,
				android.R.layout.simple_dropdown_item_1line) {
			public android.widget.Filter getFilter() {
				return tagFilter;
			}
		};

		cityAutoComplete.setAdapter(adapterCity);
		adapterCity.setNotifyOnChange(false);
		tagAutoComplete.setAdapter(adapterTag);
		adapterTag.setNotifyOnChange(false);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	/** Called when the user clicks the Send button 
	 * @throws UnsupportedEncodingException */
	public void sendMessageS(View view) throws UnsupportedEncodingException {

		AutoCompleteTextView countryAutoComplete = (AutoCompleteTextView) findViewById(R.id.countryAutoComplete);
		String country = mergeWords(countryAutoComplete.getText().toString());

		AutoCompleteTextView cityAutoComplete = (AutoCompleteTextView) findViewById(R.id.cityAutoComplete);
		String city = mergeWords(cityAutoComplete.getText().toString());

		EditText placeText = (EditText) findViewById(R.id.placeText);
		String place = mergeWords(placeText.getText().toString());

		// AutoCompleteTextView tagAutoComplete = (AutoCompleteTextView)
		// findViewById(R.id.tagAutoComplete);
		// String tags = mergeWords(tagAutoComplete.toString());

		String url = String.format(GlobalVariables.search_URL, city, country,
				place, URLEncoder.encode(selectedTagMID, "ISO-8859-1"));

		Log.w("URL", url);

		Intent intent = new Intent(this, SearchResultsActivity.class);
		intent.putExtra(EXTRA_MESSAGE, url);
		startActivity(intent);

	}

	/** connects multi word place names with "+" */
	/**
	 * @param placeName
	 * @return mergedPlaceName
	 */
	public String mergeWords(String placeName) {
		String[] parts = placeName.split(" ");
		String result = parts[0];
		for (int i = 1; i < parts.length; i++)
			result += "+" + parts[i];
		return result;
	}

	/**
	 * Gets JSON response and adds cities to an adapter.
	 * 
	 */
	public class CityAdapterUpdaterTask extends AsyncTask<Void, Void, Void> {
		List<String> completions;

		@Override
		protected Void doInBackground(Void... voids) {
			String country = countryAutoComplete.getText().toString();
			String city = cityAutoComplete.getText().toString();
			String url = "";
			try {
				url = String.format(GlobalVariables.get_cities,
						URLEncoder.encode(country, "ISO-8859-1"),
						URLEncoder.encode(city, "ISO-8859-1"));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			Log.w("url", url.toString());

			try {
				Log.w("CITYTASK-URL", url.toString());
				InputStream source = RetrieveJSONTask.retrieveStream(url);
				if (source == null) {
					Log.w("SOURCE", "NULL!!!");
					return null;
				}
				String resultJson = RetrieveJSONTask
						.getStringFromInputStream(source);
				JSONObject result = new JSONObject(resultJson);

				completions = new ArrayList<String>();
				if (result.optInt("success") == 1) {
					JSONArray cities = result.getJSONArray("data");
					for (int i = 0; i < cities.length(); i++) {
						completions.add(cities.getString(i));
					}
				}

				Log.w("COMPLETIONS", completions.size() + "");

				return null;
			} catch (NullPointerException e) {
				Log.w("NULLPTR", "");
			} catch (JSONException e) {
				Log.w("JSONEXCEPTION", "");
			}

			return null;
		}

		@Override
		protected void onPostExecute(Void aVoid) {
			adapterCity.clear();

			int size = 0;
			if (completions != null)
				size = completions.size();

			Log.w("SIZE", size + "");

			if (size > 0) {
				adapterCity.clear();
				for (int i = 0; i < size; i++) {
					adapterCity.add(completions.get(i));
				}
				adapterCity.notifyDataSetChanged();
				cityAutoComplete.showDropDown();
			}
			super.onPostExecute(aVoid);
		}
	}

	/**
	 * Gets JSON response and adds tags to an adapter.
	 * 
	 */
	public class TagTask extends RetrieveJSONTask<Tag> {
		@Override
		protected WebServiceResponse<Tag> doInBackground(String... params) {
			Type type = new TypeToken<WebServiceResponse<Tag>>() {
			}.getType();
			return super.doInBackground(type, params);
		}

		@Override
		protected void onPostExecute(WebServiceResponse<Tag> result) {
			data = result.getData();

			int size = 0;
			if (data != null)
				size = data.size();

			if (size > 0) {
				adapterTag.clear();

				for (int i = 0; i < size; i++) {
					adapterTag.add(data.get(i));
				}

				adapterTag.notifyDataSetChanged();
				tagAutoComplete.showDropDown();
			}
		}
	}
}
